﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.ServiceModel;
using Elderos.AI;
using Elderos.Highlight.Search;
using Elderos.Ontology;
using Encog.Neural.Networks;

namespace Elderos.Highlight
{
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
    public class WcfHighlighterService : IHighlighter
    {
        public WcfHighlighterService()
        {
            var ontologyString = ConfigurationManager.ConnectionStrings["Ontology"].ConnectionString;
            var ontology = new OntologyData(ontologyString);
            ontology.Initialize();

            IAmbiguityResolver ambiguityResolver = null;
            int networkID;
            if (int.TryParse(ConfigurationManager.AppSettings["networkID"], out networkID))
            {
                double threshold;
                INormalizer normalizer;
                BasicNetwork network = LoadNetworkFromDB(networkID, ontology, out threshold, out normalizer);
                ambiguityResolver = new NeuralAmbiguityResolver(threshold, network, normalizer);
                //new SimpleAmbiguityResolver(0.5);
            }
            if (ambiguityResolver == null)
                ambiguityResolver = new SimpleAmbiguityResolver(0);

            _highlighter = new Highlighter(
                new[]{new RabinKarpSearcher(ontology)},
                new SearchResultAdapter(),
                new RuleRanker(ontology),
                ambiguityResolver,
                ontology
                );
        }

        private static BasicNetwork LoadNetworkFromDB(int networkID, IOntologyData ontology, out double threshold, out INormalizer normalizer)
        {
            Network serialized = ontology.GetNetwork(networkID);

            threshold = serialized.Threshold;

            var serializer = new BinaryFormatter();
            using(var ms = new MemoryStream())
            {
                ms.Write(serialized.NormalizerData, 0, serialized.NormalizerData.Length);
                ms.Position = 0;

                normalizer = (Normalizer) serializer.Deserialize(ms);
            }

            using (var ms = new MemoryStream())
            {
                ms.Write(serialized.NetworkData, 0, serialized.NetworkData.Length);
                ms.Position = 0;

                var network = (BasicNetwork)serializer.Deserialize(ms);
                return network;
            }
        }

        private readonly Highlighter _highlighter;

        public List<Position> Search(string text)
        {
            return _highlighter.Search(text);
        }

        public HighlightResult Highlight(string text)
        {
            return _highlighter.Highlight(text);
        }

        public ArticleHighlight ProcessArticle(string text)
        {
            return _highlighter.ProcessArticle(text);
        }
    }
}
